using System;

namespace LightPersist.Transactions
{
	class UniAction<TData> : UniAction
	{
		public TData Data;

		public UniAction(TData data)
		{
			Data = data;
		}
	}

	/// <summary>
	/// Long days ago there are was 'InsertAction, RemoveAction, PropertyChangedAction, ListPropertyChangedAction'
	/// It is replaced to declarative UniAction.
	/// </summary>
	class UniAction : TheAction
	{
		public Action<TransactionProcessingContext> AfterDo;
		public Action<TransactionProcessingContext> AfterUndo;
		public Action<TransactionProcessingContext> BeforeDo;
		public Action<TransactionProcessingContext> BeforeUndo;
		public Action<TransactionProcessingContext> DoComponents;
		public Action<TransactionProcessingContext> DoModel;
		public Action<TransactionProcessingContext> DoStorage;
		public Func<string> ToStringer = () => null;
		public Action<TransactionProcessingContext> UndoComponents;
		public Action<TransactionProcessingContext> UndoModel;
		public Action<TransactionProcessingContext> UndoStorage;

		protected override string ActTypeToString
		{
			get
			{
				Debug.AssertExists(ActTypeToStringD);
				return ActTypeToStringD;
			}
		}

		/// <summary>
		/// temporary declative version
		/// </summary>
		public string ActTypeToStringD { get; set; }

		public static UniAction<T> New<T>(T data)
		{
			return new UniAction<T>(data);
		}

		public override void ProcessDo(TransactionProcessingContext ctx)
		{
			if (BeforeDo != null)
			{
				BeforeDo(ctx);
			}
			ctx.Perform(DoModel, DoComponents, DoStorage);
			if (AfterDo != null)
			{
				AfterDo(ctx);
			}
		}

		public override void ProcessUndo(TransactionProcessingContext ctx)
		{
			if (BeforeUndo != null)
			{
				BeforeUndo(ctx);
			}
			ctx.Perform(UndoModel, UndoComponents, UndoStorage);
			if (AfterUndo != null)
			{
				AfterUndo(ctx);
			}
		}

		public override string ToString()
		{
			return base.ToString() + ToStringer();
		}
	}
}